// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require('vscode');
const { cloneDeep, compact } = require(`lodash`);
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed

/**
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {

	let disposable2 = vscode.commands.registerCommand('代码融合', async function () {
		const editor = vscode.window.activeTextEditor;

		const text = editor.document.getText();



		await vscode.env.clipboard.writeText(格式化输出模板代码(text));



		const clipboardContent = await vscode.env.clipboard.readText();

		vscode.window.showInformationMessage(`生成内容已经成功复制到粘贴板`);


		// 获取当前活动的文档对象
		const activeTextEditor = vscode.window.activeTextEditor;
		const document = activeTextEditor.document;

		// 更新当前文件的内容
		const edit = new vscode.WorkspaceEdit();
		edit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), clipboardContent);
		await vscode.workspace.applyEdit(edit);

		// 提示操作成功
		vscode.window.showInformationMessage('粘贴板的内容已成功覆盖当前文件。');

		context.subscriptions.push(disposable2);




		function 格式化输出模板代码(text) {
			let 源代码片段 = 去除空数组(解析字符串为代码片段(text))
			let 结果字符串 = ''
			let 全部片段 = 分解片段(源代码片段)
			let 最终结果数组 = []
			最终结果数组 = 全部片段.头部信息.concat(全部片段.函数组件名称[0])
				.concat(全部片段.全局return之外).concat(全部片段.return合并后内容)
				.concat(['}']).concat(全部片段.export内容[0])

			flatten(最终结果数组).map((item, index) => {
				结果字符串 += item + '\n'
			})

			return 结果字符串








		}
	})

	let disposable3 = vscode.commands.registerCommand('跳转到const部分', function () {

		const activeEditor = vscode.window.activeTextEditor;
		if (activeEditor) {
			const documentUri = activeEditor.document.uri;

			vscode.window.showTextDocument(documentUri, {
				viewColumn: vscode.ViewColumn.Beside, // 在当前编辑器的旁边拆分
				preview: false, // 可选，如果设为 true，则在拆分视图中的新编辑器上进行预览
			}).then(() => {
				const editor = vscode.window.activeTextEditor;

				const text = editor.document.getText();

				let 源代码片段 = 去除空数组(解析字符串为代码片段(text))

				let 全部片段 = 分解片段(源代码片段)


				let 组件函数最后位置索引

				for (let [index, line] of text.split(/\r?\n/).entries()) {
					if (line.trim() === 全部片段.函数组件名称[0][0].trim()) {
						组件函数最后位置索引 = index + 全部片段.函数组件名称[0].length
						break
					}
				}

				if (editor) {
					const lineNumber = 组件函数最后位置索引; // 组件函数最后位置索引更改为你想要滚动到的行号
					// 在滚动到指定行后，插入一行空行
					const insertLineNumber = lineNumber;
					const insertLine = new vscode.Position(insertLineNumber, 0);
					editor.edit(editBuilder => {
						editBuilder.insert(insertLine, '\n');
					}).then(() => {
						const newPosition = new vscode.Position(insertLineNumber, 0);
						editor.selection = new vscode.Selection(newPosition, newPosition);
						editor.revealRange(new vscode.Range(newPosition, newPosition));
						vscode.window.showInformationMessage(JSON.stringify(insertLineNumber + 1));

					});

				}
			})
		}

	})
	let disposable5 = vscode.commands.registerCommand('跳转到写函数部分', function () {

		const activeEditor = vscode.window.activeTextEditor;
		if (activeEditor) {
			const documentUri = activeEditor.document.uri;

			vscode.window.showTextDocument(documentUri, {
				viewColumn: vscode.ViewColumn.Beside, // 在当前编辑器的旁边拆分
				preview: false, // 可选，如果设为 true，则在拆分视图中的新编辑器上进行预览
			}).then(() => {
				const editor = vscode.window.activeTextEditor;

				const text = editor.document.getText();

				let 源代码片段 = 去除空数组(解析字符串为代码片段(text))

				let 全部片段 = 分解片段(源代码片段)


				let 组件函数最后位置索引

				let 匹配arr = compact(全部片段.return合并后内容[1])
				let allLines = text.split(/\r?\n/)
				for (let [index, line] of allLines.entries()) {
					if (line.trim() === 匹配arr[0].trim()) {
						组件函数最后位置索引 = index
						break
					}
				}

				if (editor) {

					const lineNumber = 组件函数最后位置索引; // 组件函数最后位置索引更改为你想要滚动到的行号
					// 在滚动到指定行后，插入一行空行
					const insertLineNumber = lineNumber - 1 - 全部片段.return合并后内容[1].findIndex(item => item === 匹配arr[0]);
					const insertLine = new vscode.Position(insertLineNumber, 0);
					editor.edit(editBuilder => {
						editBuilder.insert(insertLine, '\n');
					}).then(() => {
						const newPosition = new vscode.Position(insertLineNumber, 0);
						editor.selection = new vscode.Selection(newPosition, newPosition);
						editor.revealRange(new vscode.Range(newPosition, newPosition));
						vscode.window.showInformationMessage(JSON.stringify(insertLineNumber + 1));
					});

				}
			})
		}
		context.subscriptions.push(disposable3);

	})

	let disposable4 = vscode.commands.registerCommand('跳转到dom部分', function () {

		const activeEditor = vscode.window.activeTextEditor;
		if (activeEditor) {
			const documentUri = activeEditor.document.uri;

			vscode.window.showTextDocument(documentUri, {
				viewColumn: vscode.ViewColumn.Beside, // 在当前编辑器的旁边拆分
				preview: false, // 可选，如果设为 true，则在拆分视图中的新编辑器上进行预览
			}).then(() => {
				const editor = vscode.window.activeTextEditor;

				const text = editor.document.getText();

				let 源代码片段 = 去除空数组(解析字符串为代码片段(text))

				let 全部片段 = 分解片段(源代码片段)


				let 组件函数最后位置索引
				let 匹配arr = compact(全部片段.return合并后内容[1])
				for (let [index, line] of text.split(/\r?\n/).entries()) {
					if (line.trim() === 匹配arr[0].trim()) {
						组件函数最后位置索引 = index
						break
					}
				}

				if (editor) {
					const lineNumber = 组件函数最后位置索引; // 组件函数最后位置索引更改为你想要滚动到的行号
					// 在滚动到指定行后，插入一行空行
					const insertLineNumber = lineNumber;
					const insertLine = new vscode.Position(insertLineNumber, 0);
					editor.edit(editBuilder => {
						editBuilder.insert(insertLine, '\n');
					}).then(() => {
						const newPosition = new vscode.Position(insertLineNumber, 0);
						editor.selection = new vscode.Selection(newPosition, newPosition);
						editor.revealRange(new vscode.Range(newPosition, newPosition));
						vscode.window.showInformationMessage(JSON.stringify(insertLineNumber + 1));
					});

				}
			})
		}
		context.subscriptions.push(disposable3);

	})

	// 将所有命令的 disposables 添加到扩展的 subscriptions 中
	context.subscriptions.push(disposable3, disposable4, disposable5);


	function 分解片段(源代码片段) {
		let export内容 = []
		let 头部信息 = []
		let ReactFC内容 = []
		let 全局return之外 = []
		let return合并后内容
		let 全局return内容 = []
		let 函数组件名称 = []
		for (let [index, item] of cloneDeep(源代码片段).entries()) {

			if (item[0].trim().startsWith('export default')) {
				export内容.push(item)
			} else if (item[0].indexOf('React.FC') > -1) {
				ReactFC内容.push(item)
			} else {
				头部信息.push(item)
			}
		}


		for (let [, item] of ReactFC内容.entries()) {
			let 分块的代码 = 代码分块(item)
			函数组件名称.push(...分块的代码.头部信息)
			全局return之外.push(...分块的代码.return之外)
			全局return内容.push(...分块的代码.return内容)
		}
		return合并后内容 = return合并(全局return内容)
		function return合并(return内容) {
			let newItems = []
			for (let [, item] of return内容.entries()) {
				item.splice(item.length - 1, 1)
				item.splice(0, 1)
				newItems.push(item)
			}
			let returnArr = ['return <>']
			returnArr.push(...newItems)
			returnArr.push('</>')
			return returnArr
		}

		return {
			export内容,
			头部信息,
			全局return之外,
			return合并后内容,
			函数组件名称
		}

		function 代码分块(代码片段) {
			let 头部信息 = []
			let return之外 = []
			let return内容 = []
			for (let [index, item] of 代码片段.entries()) {
				if (item.indexOf('=> {') > -1) {
					头部信息.push(代码片段.splice(0, index + 1))
					break
				}
			}

			for (let [index, item] of 代码片段.reverse().entries()) {
				if (item.trim().startsWith('}') > -1) {
					代码片段.splice(index, 1)
					break
				}
			}

			代码片段.reverse()

			for (let [, item] of 解析字符串为代码片段(代码片段.join('\n')).entries()) {
				if (item[0].trim().startsWith('return')) {
					return内容.push(item)
				} else {
					return之外.push(item)
				}
			}

			return {
				return之外,
				return内容,
				头部信息
			}
		}
	}


	function flatten(arr) {
		return arr.reduce((result, item) => {
			return result.concat(Array.isArray(item) ? flatten(item) : item);
		}, []);
	}

	function 解析字符串为代码片段(源代码字符串) {
		let 源代码片段 = []
		let 匹配键值对 = {
			'{': '}',
			'[': ']',
			'(': ')',
		}
		let 临时代码 = []
		let 括号数组 = []

		源代码字符串.split(/\r?\n/).forEach((line) => {

			临时代码.push(line)
			if (line) {
				for (let [key, value] of Object.entries(匹配键值对)) {// 遍历对象
					let 转义的键 = '\\' + key.split('').join('\\')
					let 转义的值 = '\\' + value.split('').join('\\')
					let 匹配到的键 = line.match(eval("/" + 转义的键 + "/g"))
					let 匹配到的值 = line.match(eval("/" + 转义的值 + "/g"))
					if (匹配到的键) {
						for (let [, item] of 匹配到的键.entries()) {
							括号数组.push(item)
						}
					}
					if (匹配到的值) {
						for (let [, item] of 匹配到的值.entries()) {
							括号数组.splice(0, 1)
						}
					}
				}
			}

			let 最后一个不是等于号 = (line.trim().substring(line.trim().length - 1, line.trim().length) !== '=')
			if (最后一个不是等于号 && 括号数组.length == 0) {
				源代码片段.push(临时代码)
				临时代码 = []
			}
		})
		return 源代码片段
	}


	function 去除空数组(原数组) {
		let 要被删除的数组 = []

		for (let [i, item] of 原数组.entries()) {
			if (item.length === 1 && item[0] === '' || item.length === 0) {
				要被删除的数组.push(i)
			}
		}
		要被删除的数组 = 要被删除的数组.reverse()
		for (let [, item] of 要被删除的数组.entries()) {
			原数组.splice(item, 1)
		}
		return 原数组
	}
}

// This method is called when your extension is deactivated
function deactivate() { }

module.exports = {
	activate,
	deactivate
}
